package com.one.blocks.mvc.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelAnalysisStopException;
import com.one.blocks.mvc.enums.BatchResultEnum;
import com.one.blocks.mvc.manager.BatchManager;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author linfuxin Created on 2022-07-12 14:12:48
 */
public class RollbackOfErrorListener<T, E, Convert extends ExcelConvert<T, E>, Manager extends BatchManager<T> & ExcelManager<T>>
        extends AbstractDataListener<T, E, Convert, Manager> {

    private final List<T> cachedDataList = new ArrayList<>();
    private Integer errorIndex;
    private int importSuccessCount;
    private int updateSuccessCount;

    public RollbackOfErrorListener(Manager manager, Convert convert, UploadParam uploadParam, UploadResult uploadResult, Class<T> tClazz, Class<E> eClazz) {
        super(manager, convert, uploadParam, uploadResult, tClazz, eClazz);
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        uploadResult.setState(BatchResultEnum.FAILED.getCode());
        uploadResult.setFailedReason(exception.getMessage());
        uploadResult.setDetail(String.format("新增%d条,覆盖%d条,在导入第%d行数据时出现异常!",
                importSuccessCount, updateSuccessCount, context.readRowHolder().getRowIndex()));
        if (exception instanceof ExcelAnalysisStopException) {
            throw exception;
        }
        throw new ExcelAnalysisStopException();
    }

    @Override
    protected void doInvoke(E data, AnalysisContext context) {
        cachedDataList.add(convert.excelToEntity(data));
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        super.doAfterAllAnalysed(context);
        saveData();

        uploadResult.setState(BatchResultEnum.SUCCESS.getCode());
        uploadResult.setDetail(String.format("导入成功%d条数据!", importSuccessCount));
    }

    @Override
    protected void updateBatch(List<T> updateDataList) {
        updateSuccessCount += updateDataList.size();
    }

    protected void saveData() {
        if (CollectionUtils.isEmpty(cachedUpdateDataList)) {
            manager.insertBatch(cachedDataList);
        } else {
            cachedDataList.addAll(cachedUpdateDataList);
            manager.saveBatch(cachedDataList);
        }
        importSuccessCount += cachedDataList.size();
    }
}
